package com.yhh.college_information_platform.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yhh.college_information_platform.common.PageResult;
import com.yhh.college_information_platform.common.ResultCode;
import com.yhh.college_information_platform.dto.ResourceQueryDTO;
import com.yhh.college_information_platform.dto.ResourceUploadDTO;
import com.yhh.college_information_platform.entity.Category;
import com.yhh.college_information_platform.entity.Favorite;
import com.yhh.college_information_platform.entity.Like;
import com.yhh.college_information_platform.entity.Resource;
import com.yhh.college_information_platform.entity.User;
import com.yhh.college_information_platform.exception.BusinessException;
import com.yhh.college_information_platform.mapper.CategoryMapper;
import com.yhh.college_information_platform.mapper.FavoriteMapper;
import com.yhh.college_information_platform.mapper.LikeMapper;
import com.yhh.college_information_platform.mapper.ResourceMapper;
import com.yhh.college_information_platform.mapper.UserMapper;
import com.yhh.college_information_platform.service.NotificationService;
import com.yhh.college_information_platform.service.ResourceService;
import com.yhh.college_information_platform.utils.MinioUtil;
import com.yhh.college_information_platform.vo.ResourceVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 资料Service实现类
 *
 * @author yhh
 * @date 2025-10-25
 */
@Slf4j
@Service
public class ResourceServiceImpl implements ResourceService {

    @Autowired
    private ResourceMapper resourceMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private CategoryMapper categoryMapper;

    @Autowired
    private LikeMapper likeMapper;

    @Autowired
    private FavoriteMapper favoriteMapper;

    @Autowired
    private MinioUtil minioUtil;
    
    @Autowired
    private NotificationService notificationService;

    @Autowired
    private com.yhh.college_information_platform.service.FilePreviewService filePreviewService;

    @Value("${file.allowed-types}")
    private String allowedTypes;

    @Value("${file.max-size}")
    private Long maxFileSize;

    @Override
    public PageResult<ResourceVO> getResourcePage(ResourceQueryDTO queryDTO, Long userId) {
        // 构建查询条件
        LambdaQueryWrapper<Resource> wrapper = new LambdaQueryWrapper<>();
        
        // 关键词搜索
        if (StrUtil.isNotBlank(queryDTO.getKeyword())) {
            wrapper.and(w -> w.like(Resource::getTitle, queryDTO.getKeyword())
                    .or()
                    .like(Resource::getDescription, queryDTO.getKeyword()));
        }
        
        // 分类筛选
        if (queryDTO.getCategoryId() != null) {
            // 查询分类信息，判断是一级分类还是二级分类
            Category category = categoryMapper.selectById(queryDTO.getCategoryId());
            if (category != null && category.getLevel() == 1) {
                // 如果是一级分类，查询其所有子分类的资料
                LambdaQueryWrapper<Category> catWrapper = new LambdaQueryWrapper<>();
                catWrapper.eq(Category::getParentId, queryDTO.getCategoryId());
                List<Category> subCategories = categoryMapper.selectList(catWrapper);
                
                if (!subCategories.isEmpty()) {
                    List<Long> categoryIds = subCategories.stream()
                            .map(Category::getId)
                            .collect(Collectors.toList());
                    wrapper.in(Resource::getCategoryId, categoryIds);
                } else {
                    // 如果没有子分类，直接查询该分类
                    wrapper.eq(Resource::getCategoryId, queryDTO.getCategoryId());
                }
            } else {
                // 如果是二级分类，直接查询
                wrapper.eq(Resource::getCategoryId, queryDTO.getCategoryId());
            }
        }
        
        // 标签筛选
        if (StrUtil.isNotBlank(queryDTO.getTag())) {
            wrapper.like(Resource::getTags, queryDTO.getTag());
        }
        
        // 文件类型筛选（支持多选，用逗号分隔）
        if (StrUtil.isNotBlank(queryDTO.getFileType())) {
            String fileTypes = queryDTO.getFileType();
            if (fileTypes.contains(",")) {
                // 多个文件类型，使用 in 查询
                List<String> fileTypeList = Arrays.asList(fileTypes.split(","));
                wrapper.in(Resource::getFileType, fileTypeList);
            } else {
                // 单个文件类型，使用 eq 查询
                wrapper.eq(Resource::getFileType, fileTypes);
            }
        }
        
        // 上传者筛选
        if (queryDTO.getUploaderId() != null) {
            wrapper.eq(Resource::getUploaderId, queryDTO.getUploaderId());
        }
        
        // 状态筛选（默认只查询审核通过的）
        if (queryDTO.getStatus() != null) {
            wrapper.eq(Resource::getStatus, queryDTO.getStatus());
        } else {
            wrapper.eq(Resource::getStatus, 1); // 默认只显示审核通过的
        }
        
        // 排序
        String orderBy = queryDTO.getOrderBy();
        boolean isAsc = "asc".equals(queryDTO.getOrderType());
        
        switch (orderBy) {
            case "download_count":
                wrapper.orderBy(true, isAsc, Resource::getDownloadCount);
                break;
            case "like_count":
                wrapper.orderBy(true, isAsc, Resource::getLikeCount);
                break;
            case "view_count":
                wrapper.orderBy(true, isAsc, Resource::getViewCount);
                break;
            default:
                wrapper.orderBy(true, isAsc, Resource::getCreateTime);
        }
        
        // 分页查询
        Page<Resource> page = new Page<>(queryDTO.getCurrent(), queryDTO.getSize());
        Page<Resource> resultPage = resourceMapper.selectPage(page, wrapper);
        
        // 转换为VO，并设置点赞/收藏状态
        List<ResourceVO> voList = resultPage.getRecords().stream()
                .map(resource -> {
                    ResourceVO vo = convertToVO(resource);
                    // 如果有userId，查询点赞/收藏状态
                    if (userId != null) {
                        vo.setIsLiked(checkIsLiked(userId, resource.getId()));
                        vo.setIsFavorited(checkIsFavorited(userId, resource.getId()));
                    } else {
                        vo.setIsLiked(false);
                        vo.setIsFavorited(false);
                    }
                    return vo;
                })
                .collect(Collectors.toList());
        
        return new PageResult<>(voList, resultPage.getTotal(), resultPage.getSize(), resultPage.getCurrent());
    }

    @Override
    public List<ResourceVO> getLatestResources(Integer limit) {
        LambdaQueryWrapper<Resource> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Resource::getStatus, 1)
                .orderByDesc(Resource::getCreateTime)
                .last("LIMIT " + limit);
        
        List<Resource> resources = resourceMapper.selectList(wrapper);
        return resources.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    public List<ResourceVO> getHotResources(Integer limit) {
        LambdaQueryWrapper<Resource> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Resource::getStatus, 1)
                .orderByDesc(Resource::getDownloadCount)
                .orderByDesc(Resource::getLikeCount)
                .last("LIMIT " + limit);
        
        List<Resource> resources = resourceMapper.selectList(wrapper);
        return resources.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    public ResourceVO getResourceById(Long id, Long userId) {
        Resource resource = resourceMapper.selectById(id);
        if (resource == null) {
            throw new BusinessException(ResultCode.PARAM_ERROR, "资料不存在");
        }
        
        ResourceVO vo = convertToVO(resource);
        
        // 查询当前用户是否点赞/收藏
        if (userId != null) {
            vo.setIsLiked(checkIsLiked(userId, id));
            vo.setIsFavorited(checkIsFavorited(userId, id));
        } else {
            vo.setIsLiked(false);
            vo.setIsFavorited(false);
        }
        
        return vo;
    }

    @Override
    public PageResult<ResourceVO> getUserResources(Long userId, Integer current, Integer size) {
        LambdaQueryWrapper<Resource> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Resource::getUploaderId, userId)
                .orderByDesc(Resource::getCreateTime);
        
        Page<Resource> page = new Page<>(current, size);
        Page<Resource> resultPage = resourceMapper.selectPage(page, wrapper);
        
        List<ResourceVO> voList = resultPage.getRecords().stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
        
        return new PageResult<>(voList, resultPage.getTotal(), resultPage.getSize(), resultPage.getCurrent());
    }

    @Override
    public void incrementViewCount(Long id) {
        Resource resource = resourceMapper.selectById(id);
        if (resource != null) {
            resource.setViewCount(resource.getViewCount() + 1);
            resourceMapper.updateById(resource);
        }
    }

    @Override
    public void incrementDownloadCount(Long id) {
        Resource resource = resourceMapper.selectById(id);
        if (resource != null) {
            resource.setDownloadCount(resource.getDownloadCount() + 1);
            resourceMapper.updateById(resource);
        }
    }

    /**
     * 转换为VO对象
     */
    private ResourceVO convertToVO(Resource resource) {
        ResourceVO vo = BeanUtil.copyProperties(resource, ResourceVO.class);
        
        // 查询分类名称
        if (resource.getCategoryId() != null) {
            Category category = categoryMapper.selectById(resource.getCategoryId());
            if (category != null) {
                vo.setCategoryName(category.getName());
            }
        }
        
        // 查询上传者信息
        if (resource.getUploaderId() != null) {
            User uploader = userMapper.selectById(resource.getUploaderId());
            if (uploader != null) {
                vo.setUploaderName(uploader.getNickname());
                vo.setUploaderAvatar(uploader.getAvatar());
            }
        }
        
        // 处理标签
        if (StrUtil.isNotBlank(resource.getTags())) {
            vo.setTags(Arrays.asList(resource.getTags().split(",")));
        }
        
        // 格式化文件大小
        vo.setFileSizeFormat(formatFileSize(resource.getFileSize()));
        
        // 设置预览支持信息
        if (StrUtil.isNotBlank(resource.getFileType())) {
            String previewType = filePreviewService.getPreviewType(resource.getFileType());
            boolean supportPreview = filePreviewService.isSupportPreview(resource.getFileType());
            vo.setPreviewType(previewType);
            vo.setSupportPreview(supportPreview);
        } else {
            vo.setPreviewType("unsupported");
            vo.setSupportPreview(false);
        }
        
        return vo;
    }

    /**
     * 格式化文件大小
     */
    private String formatFileSize(Long size) {
        if (size == null || size == 0) {
            return "0 B";
        }
        
        DecimalFormat df = new DecimalFormat("#.##");
        if (size < 1024) {
            return size + " B";
        } else if (size < 1024 * 1024) {
            return df.format(size / 1024.0) + " KB";
        } else if (size < 1024 * 1024 * 1024) {
            return df.format(size / (1024.0 * 1024.0)) + " MB";
        } else {
            return df.format(size / (1024.0 * 1024.0 * 1024.0)) + " GB";
        }
    }

    /**
     * 检查用户是否点赞了资料
     */
    private Boolean checkIsLiked(Long userId, Long resourceId) {
        if (userId == null || resourceId == null) {
            return false;
        }
        LambdaQueryWrapper<Like> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Like::getUserId, userId)
                .eq(Like::getResourceId, resourceId);
        Long count = likeMapper.selectCount(wrapper);
        return count > 0;
    }

    /**
     * 检查用户是否收藏了资料
     */
    private Boolean checkIsFavorited(Long userId, Long resourceId) {
        if (userId == null || resourceId == null) {
            return false;
        }
        LambdaQueryWrapper<Favorite> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Favorite::getUserId, userId)
                .eq(Favorite::getResourceId, resourceId);
        Long count = favoriteMapper.selectCount(wrapper);
        return count > 0;
    }

    @Override
    public String uploadFile(MultipartFile file) {
        try {
            // 1. 校验文件
            validateFile(file);

            // 2. 上传到MinIO
            String fileUrl = minioUtil.uploadFile(file);
            log.info("文件上传成功，URL: {}", fileUrl);

            return fileUrl;
        } catch (Exception e) {
            log.error("文件上传失败", e);
            throw new BusinessException(ResultCode.SYSTEM_ERROR, "文件上传失败: " + e.getMessage());
        }
    }

    @Override
    public String uploadCoverImage(MultipartFile file) {
        try {
            // 1. 校验图片文件
            validateCoverImage(file);

            // 2. 上传到MinIO
            String coverUrl = minioUtil.uploadFile(file);
            log.info("封面图片上传成功，URL: {}", coverUrl);

            return coverUrl;
        } catch (Exception e) {
            log.error("封面图片上传失败", e);
            throw new BusinessException(ResultCode.SYSTEM_ERROR, "封面图片上传失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long uploadResource(ResourceUploadDTO uploadDTO, Long userId) {
        // 1. 验证分类是否存在
        Category category = categoryMapper.selectById(uploadDTO.getCategoryId());
        if (category == null) {
            throw new BusinessException(ResultCode.PARAM_ERROR, "分类不存在");
        }

        // 2. 创建资料实体
        Resource resource = new Resource();
        resource.setTitle(uploadDTO.getTitle());
        resource.setDescription(uploadDTO.getDescription());
        resource.setCategoryId(uploadDTO.getCategoryId());
        resource.setTags(uploadDTO.getTags());
        resource.setFileName(uploadDTO.getFileName());
        resource.setFileSize(uploadDTO.getFileSize());
        resource.setFileType(uploadDTO.getFileType());
        resource.setFileUrl(uploadDTO.getFileUrl());
        resource.setCoverUrl(uploadDTO.getCoverUrl());
        resource.setUploaderId(userId);
        resource.setStatus(0); // 待审核状态
        resource.setDownloadCount(0);
        resource.setLikeCount(0);
        resource.setFavoriteCount(0);
        resource.setCommentCount(0);
        resource.setViewCount(0);

        // 3. 保存到数据库
        int rows = resourceMapper.insert(resource);
        if (rows <= 0) {
            throw new BusinessException(ResultCode.SYSTEM_ERROR, "资料保存失败");
        }

        log.info("资料上传成功，资料ID: {}, 标题: {}, 上传者ID: {}", resource.getId(), resource.getTitle(), userId);
        return resource.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteResource(Long id, Long userId) {
        // 1. 查询资料
        Resource resource = resourceMapper.selectById(id);
        if (resource == null) {
            throw new BusinessException(ResultCode.PARAM_ERROR, "资料不存在");
        }

        // 2. 验证权限（只有上传者本人可以删除）
        if (!resource.getUploaderId().equals(userId)) {
            throw new BusinessException(ResultCode.NO_PERMISSION, "无权删除该资料");
        }

        // 3. 删除MinIO中的文件
        try {
            minioUtil.deleteFileByUrl(resource.getFileUrl());
            if (StrUtil.isNotBlank(resource.getCoverUrl())) {
                minioUtil.deleteFileByUrl(resource.getCoverUrl());
            }
        } catch (Exception e) {
            log.error("删除文件失败", e);
            // 继续删除数据库记录
        }

        // 4. 删除数据库记录
        resourceMapper.deleteById(id);
        log.info("资料删除成功，资料ID: {}, 标题: {}", id, resource.getTitle());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateResource(Long id, ResourceUploadDTO uploadDTO, Long userId) {
        // 1. 查询资料
        Resource resource = resourceMapper.selectById(id);
        if (resource == null) {
            throw new BusinessException(ResultCode.PARAM_ERROR, "资料不存在");
        }

        // 2. 验证权限（只有上传者本人可以修改）
        if (!resource.getUploaderId().equals(userId)) {
            throw new BusinessException(ResultCode.NO_PERMISSION, "无权修改该资料");
        }

        // 3. 验证分类是否存在
        Category category = categoryMapper.selectById(uploadDTO.getCategoryId());
        if (category == null) {
            throw new BusinessException(ResultCode.PARAM_ERROR, "分类不存在");
        }

        // 4. 更新资料信息
        resource.setTitle(uploadDTO.getTitle());
        resource.setDescription(uploadDTO.getDescription());
        resource.setCategoryId(uploadDTO.getCategoryId());
        resource.setTags(uploadDTO.getTags());

        // 如果更新了文件，需要删除旧文件
        if (!resource.getFileUrl().equals(uploadDTO.getFileUrl())) {
            try {
                minioUtil.deleteFileByUrl(resource.getFileUrl());
            } catch (Exception e) {
                log.error("删除旧文件失败", e);
            }
            resource.setFileName(uploadDTO.getFileName());
            resource.setFileSize(uploadDTO.getFileSize());
            resource.setFileType(uploadDTO.getFileType());
            resource.setFileUrl(uploadDTO.getFileUrl());
        }

        // 如果更新了封面图
        if (StrUtil.isNotBlank(uploadDTO.getCoverUrl()) && !uploadDTO.getCoverUrl().equals(resource.getCoverUrl())) {
            if (StrUtil.isNotBlank(resource.getCoverUrl())) {
                try {
                    minioUtil.deleteFileByUrl(resource.getCoverUrl());
                } catch (Exception e) {
                    log.error("删除旧封面图失败", e);
                }
            }
            resource.setCoverUrl(uploadDTO.getCoverUrl());
        }

        // 修改后需要重新审核
        resource.setStatus(0);
        resource.setAuditRemark(null);

        // 5. 更新数据库
        int rows = resourceMapper.updateById(resource);
        if (rows <= 0) {
            throw new BusinessException(ResultCode.SYSTEM_ERROR, "资料更新失败");
        }

        log.info("资料更新成功，资料ID: {}, 标题: {}", id, resource.getTitle());
    }

    /**
     * 校验文件
     */
    private void validateFile(MultipartFile file) {
        if (file == null || file.isEmpty()) {
            throw new BusinessException(ResultCode.PARAM_ERROR, "文件不能为空");
        }

        // 校验文件大小
        if (file.getSize() > maxFileSize) {
            throw new BusinessException(ResultCode.PARAM_ERROR, 
                    "文件大小超过限制，最大允许 " + formatFileSize(maxFileSize));
        }

        // 校验文件类型
        String originalFilename = file.getOriginalFilename();
        if (StrUtil.isBlank(originalFilename)) {
            throw new BusinessException(ResultCode.PARAM_ERROR, "文件名不能为空");
        }

        String extension = "";
        if (originalFilename.contains(".")) {
            extension = originalFilename.substring(originalFilename.lastIndexOf(".") + 1).toLowerCase();
        }

        if (StrUtil.isBlank(extension)) {
            throw new BusinessException(ResultCode.PARAM_ERROR, "文件必须有扩展名");
        }

        // 检查是否在允许的类型列表中
        List<String> allowedTypeList = Arrays.asList(allowedTypes.split(","));
        if (!allowedTypeList.contains(extension)) {
            throw new BusinessException(ResultCode.PARAM_ERROR, 
                    "不支持的文件类型，仅支持: " + allowedTypes);
        }
    }

    /**
     * 校验封面图片
     */
    private void validateCoverImage(MultipartFile file) {
        if (file == null || file.isEmpty()) {
            throw new BusinessException(ResultCode.PARAM_ERROR, "图片文件不能为空");
        }

        // 校验文件大小（图片限制为5MB）
        long maxImageSize = 5 * 1024 * 1024; // 5MB
        if (file.getSize() > maxImageSize) {
            throw new BusinessException(ResultCode.PARAM_ERROR, 
                    "图片大小超过限制，最大允许 5MB");
        }

        // 校验文件类型
        String originalFilename = file.getOriginalFilename();
        if (StrUtil.isBlank(originalFilename)) {
            throw new BusinessException(ResultCode.PARAM_ERROR, "文件名不能为空");
        }

        String extension = "";
        if (originalFilename.contains(".")) {
            extension = originalFilename.substring(originalFilename.lastIndexOf(".") + 1).toLowerCase();
        }

        if (StrUtil.isBlank(extension)) {
            throw new BusinessException(ResultCode.PARAM_ERROR, "文件必须有扩展名");
        }

        // 允许的图片类型
        List<String> allowedImageTypes = Arrays.asList("jpg", "jpeg", "png", "gif", "bmp", "webp");
        if (!allowedImageTypes.contains(extension)) {
            throw new BusinessException(ResultCode.PARAM_ERROR, 
                    "不支持的图片格式，仅支持: jpg, jpeg, png, gif, bmp, webp");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void auditResource(Long id, Integer status, String rejectReason, Long adminId) {
        // 1. 验证资料是否存在
        Resource resource = resourceMapper.selectById(id);
        if (resource == null) {
            throw new BusinessException(ResultCode.PARAM_ERROR, "资料不存在");
        }

        // 2. 验证状态
        if (status != 1 && status != 2) {
            throw new BusinessException(ResultCode.PARAM_ERROR, "审核状态不正确");
        }

        // 3. 如果拒绝，必须填写原因
        if (status == 2 && StrUtil.isBlank(rejectReason)) {
            throw new BusinessException(ResultCode.PARAM_ERROR, "拒绝审核必须填写原因");
        }

        // 4. 更新资料状态
        Resource updateResource = new Resource();
        updateResource.setId(id);
        updateResource.setStatus(status);
        updateResource.setAuditRemark(rejectReason);

        int rows = resourceMapper.updateById(updateResource);
        if (rows <= 0) {
            throw new BusinessException(ResultCode.SYSTEM_ERROR, "审核失败");
        }
        
        // 5. 发送审核通知给资料上传者
        notificationService.sendAuditNotification(
            resource.getId(),
            resource.getTitle(),
            resource.getUploaderId(),
            status == 1, // true表示审核通过，false表示拒绝
            rejectReason
        );

        log.info("管理员{}审核资料成功，资料ID: {}, 审核结果: {}", adminId, id, status == 1 ? "通过" : "拒绝");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteResourceByAdmin(Long id, Long adminId) {
        // 1. 验证资料是否存在
        Resource resource = resourceMapper.selectById(id);
        if (resource == null) {
            throw new BusinessException(ResultCode.PARAM_ERROR, "资料不存在");
        }

        // 2. 删除文件（MinIO）
        if (StrUtil.isNotBlank(resource.getFileUrl())) {
            try {
                minioUtil.deleteFileByUrl(resource.getFileUrl());
                log.info("删除资料文件成功: {}", resource.getFileUrl());
            } catch (Exception e) {
                log.error("删除资料文件失败", e);
            }
        }

        // 3. 删除封面图（如果有）
        if (StrUtil.isNotBlank(resource.getCoverUrl())) {
            try {
                minioUtil.deleteFileByUrl(resource.getCoverUrl());
                log.info("删除封面图成功: {}", resource.getCoverUrl());
            } catch (Exception e) {
                log.error("删除封面图失败", e);
            }
        }

        // 4. 删除数据库记录
        int rows = resourceMapper.deleteById(id);
        if (rows <= 0) {
            throw new BusinessException(ResultCode.SYSTEM_ERROR, "删除失败");
        }

        log.info("管理员{}删除资料成功，资料ID: {}, 标题: {}", adminId, id, resource.getTitle());
    }

    @Override
    public String getDownloadUrl(Long id, Long userId) {
        // 1. 查询资料
        Resource resource = resourceMapper.selectById(id);
        if (resource == null) {
            throw new BusinessException(ResultCode.PARAM_ERROR, "资料不存在");
        }

        // 2. 检查资料状态（只有已审核通过的资料才能下载）
        if (resource.getStatus() != 1) {
            throw new BusinessException(ResultCode.NO_PERMISSION, "资料未通过审核，无法下载");
        }

        // 3. 返回文件URL
        return resource.getFileUrl();
    }

    @Override
    public java.util.Map<String, String> getDownloadInfo(Long id, Long userId) {
        // 1. 查询资料
        Resource resource = resourceMapper.selectById(id);
        if (resource == null) {
            throw new BusinessException(ResultCode.PARAM_ERROR, "资料不存在");
        }

        // 2. 检查资料状态（只有已审核通过的资料才能下载）
        if (resource.getStatus() != 1) {
            throw new BusinessException(ResultCode.NO_PERMISSION, "资料未通过审核，无法下载");
        }

        // 3. 返回文件URL和原始文件名
        java.util.Map<String, String> result = new java.util.HashMap<>();
        result.put("fileUrl", resource.getFileUrl());
        result.put("fileName", resource.getFileName());
        
        return result;
    }
}

